/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package eu.easyedu.dictionary.api.model;

import eu.easyedu.dictionary.api.service.events.CreateEntityDictionaryEvent;
import eu.easyedu.dictionary.api.service.events.WordBookEventListener;
import eu.easyedu.dictionary.api.util.ConnectionDoesNotExistsException;
import eu.easyedu.dictionary.api.util.DatabaseUtils;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Logger;
import org.openide.nodes.Node;
import org.openide.nodes.PropertySupport;
import org.openide.util.Exceptions;

/**
 *
 * @author hlavki
 */
public class Dictionary implements Comparable<Dictionary>, java.io.Serializable {

    private static final long serialVersionUID = 1L;
    private static final Logger log = Logger.getLogger(Dictionary.class.getName());
//    private transient AsynchronousSearch search;
    private transient PropertyChangeSupport pceListeners;
    private transient List<WordBookEventListener> wordBookEventListeners;
    private String name;
    private String connectionName;

    public Dictionary(String name, String connectionName) {
        this.name = name;
        this.connectionName = connectionName;
//        this.persistenceProvider = Lookup.getDefault().lookup(PersistenceProvider.class);
//        this.persistenceProvider.setConnection(DatabaseUtils.getConnection(connectionName));
//        log.info("Connection found: " + persistenceProvider);
        pceListeners = new PropertyChangeSupport(this);
//        search = new AsynchronousSearch(this);
        wordBookEventListeners = new ArrayList<WordBookEventListener>();
    }

    public Dictionary(String name) throws ConnectionDoesNotExistsException {
        this(name, DatabaseUtils.getDefaultConnection().getName());
    }

    public String getConnectionName() {
        return connectionName;
    }

    public String getName() {
        return name;
    }

//    public void setLanguage(Language language) {
//        Language oldValue = this.language;
//        this.language = language;
//        pceListeners.firePropertyChange("language", oldValue, language);
//    }
//
//    public void search(String searchString) {
//        DictionaryPersistenceProvider persistenceProvider = Lookup.getDefault().lookup(DictionaryPersistenceProvider.class);
//        if (searchString.length() > 2) {
//            if (!persistenceProvider.isConnected()) {
//                log.warning("Connection is not active. Activating...");
//                persistenceProvider.connect();
//            }
//            search.search(searchString, language);
//        }
//    }

//    protected WordBookService getWordBookService() {
//        return Lookup.getDefault().lookup(WordBookService.class);
//    }
//
//    protected DictionaryService getDictionaryService() {
//        DictionaryService service = Lookup.getDefault().lookup(DictionaryService.class);
//        log.info("DictionaryService looked up " + service);
//        return service;
//    }

//    public Language addLanguage(Language language) {
//        Language newLanguage = getWordBookService().addLanguage(language);
//        fireAddLangaugeEvent(newLanguage);
//        return newLanguage;
//    }
//
//    public Word addWord(Word word, List<WordRelationship> relationships) {
//        Word newWord = getWordBookService().addWord(word, relationships);
//        fireAddWordEvent(newWord);
//        return newWord;
//    }
//
//    public Word addWord(Word word) {
//        Word newWord = getWordBookService().addWord(word);
//        fireAddWordEvent(newWord);
//        return newWord;
//    }
//
//    public void addRelationships(List<WordRelationship> relationships) {
//        getWordBookService().addRelationships(relationships);
//    }
//
//    public List<WordRelationship> getAllRelatedWords(Word word) {
//        return getWordBookService().getAllRelatedWords(word);
//    }
//
//    public List<Language> getAllLanguages() {
//        return getDictionaryService().getAllLanguages();
//    }
//
//    public Language getLanguage(String code) {
//        return getWordBookService().getLanguage(code);
//    }
//
//    public Word getWord(String word, Long languageId) {
//        return getWordBookService().getWord(word, languageId);
//    }
//
//    public Word getWord(String word, Language language) {
//        return getWordBookService().getWord(word, language.getId());
//    }

    public void addWordBookEventListener(WordBookEventListener listener) {
        wordBookEventListeners.add(listener);
    }

    public void removeWordBookEventListener(WordBookEventListener listener) {
        wordBookEventListeners.remove(listener);
    }

//    public void addConnectionEventListener(ConnectionEventListener listener) {
//        DictionaryPersistenceProvider persistenceProvider = Lookup.getDefault().lookup(DictionaryPersistenceProvider.class);
//        persistenceProvider.getConnection().addConnectionEventListener(listener);
//    }
//
//    public void removeConnectionEventListener(ConnectionEventListener listener) {
//        DictionaryPersistenceProvider persistenceProvider = Lookup.getDefault().lookup(DictionaryPersistenceProvider.class);
//        persistenceProvider.getConnection().removeConnectionEventListener(listener);
//    }

    // The listener list wrapper methods.
    public synchronized void addPropertyChangeListener(PropertyChangeListener listener) {
        pceListeners.addPropertyChangeListener(listener);
    }

    public synchronized void removePropertyChangeListener(PropertyChangeListener listener) {
        pceListeners.removePropertyChangeListener(listener);
    }

    protected void fireAddWordEvent(Word word) {
        CreateEntityDictionaryEvent<Word> evt = new CreateEntityDictionaryEvent<Word>(word);
        for (WordBookEventListener listener : wordBookEventListeners) {
            listener.addWord(evt);
        }
    }

    protected void fireAddLangaugeEvent(Language language) {
        CreateEntityDictionaryEvent<Language> evt = new CreateEntityDictionaryEvent<Language>(language);
        for (WordBookEventListener listener : wordBookEventListeners) {
            listener.addLanguage(evt);
        }
    }

//    public void addSearchEventListener(SearchEventListener listener) {
//        search.addSearchEventListener(listener);
//    }
//
//    public void removeSearchEventListener(SearchEventListener listener) {
//        search.removeSearchEventListener(listener);
//    }

    @Override
    public String toString() {
        return name;
    }

    public int compareTo(Dictionary o) {
        return this.name.compareTo(o.getName());
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final Dictionary other = (Dictionary) obj;
        if (this.connectionName != other.connectionName &&
                (this.connectionName == null || !this.connectionName.equals(other.connectionName))) {
            return false;
        }
        return true;
    }

    @Override
    public int hashCode() {
        int hash = 7;
        hash = 29 * hash + (this.connectionName != null ? this.connectionName.hashCode() : 0);
        return hash;
    }

    public Node.Property[] getNodeProperties() {
        Node.Property[] props = new Node.Property[2];
        try {
            props[0] = new PropertySupport.Reflection<String>(this, String.class, "getName", null);
            props[0].setName("Name");
            props[1] = new PropertySupport.Reflection<String>(this, String.class, "getConnectionName", null);
            props[1].setName("Connection");
        } catch (NoSuchMethodException ex) {
            Exceptions.printStackTrace(ex);
        }
        return props;
    }

}
